package com.cardcaptorsakura.controller;

import com.cardcaptorsakura.model.dto.*;
import com.cardcaptorsakura.service.output.MultiModalOutputService;
import com.cardcaptorsakura.service.output.TextGenerationService;
import com.cardcaptorsakura.service.output.ImageGenerationService;
import com.cardcaptorsakura.service.output.VoiceSynthesisService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 多模态输出控制器
 * 提供文本生成、图像生成、语音合成等多模态输出API
 */
@Slf4j
@RestController
@RequestMapping("/api/output")
@RequiredArgsConstructor
@Validated
@Tag(name = "多模态输出", description = "多模态输出相关API")
public class MultiModalOutputController {

    private final MultiModalOutputService multiModalOutputService;
    private final TextGenerationService textGenerationService;
    private final ImageGenerationService imageGenerationService;
    private final VoiceSynthesisService voiceSynthesisService;

    /**
     * 多模态输出处理
     */
    @PostMapping("/multimodal")
    @Operation(summary = "多模态输出处理", description = "根据请求生成文本、图像、语音等多种形式的输出")
    public ResponseEntity<ApiResponse<MultiModalOutputResponse>> processMultiModalOutput(
            @Valid @RequestBody MultiModalOutputRequest request) {
        
        try {
            log.info("Processing multi-modal output request for user: {}", request.getUserId());
            
            MultiModalOutputResponse response = multiModalOutputService.processMultiModalOutput(request);
            
            return ResponseEntity.ok(ApiResponse.success(response));
            
        } catch (Exception e) {
            log.error("Error processing multi-modal output", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("处理多模态输出失败: " + e.getMessage()));
        }
    }

    /**
     * 文本生成
     */
    @PostMapping("/text")
    @Operation(summary = "文本生成", description = "根据用户输入生成个性化文本回复")
    public ResponseEntity<ApiResponse<String>> generateText(
            @Valid @RequestBody ChatRequest request) {
        
        try {
            log.info("Generating text for user: {}", request.getUserId());
            
            String response = textGenerationService.generateText(request);
            
            return ResponseEntity.ok(ApiResponse.success(response));
            
        } catch (Exception e) {
            log.error("Error generating text", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("文本生成失败: " + e.getMessage()));
        }
    }

    /**
     * 图像生成
     */
    @PostMapping("/image")
    @Operation(summary = "图像生成", description = "根据文本描述生成图像")
    public ResponseEntity<ApiResponse<ImageGenerationResponse>> generateImage(
            @Valid @RequestBody ImageGenerationRequest request) {
        
        try {
            log.info("Generating image for user: {}, prompt: {}", 
                    request.getUserId(), request.getPrompt());
            
            ImageGenerationResponse response = imageGenerationService.generateImage(request);
            
            return ResponseEntity.ok(ApiResponse.success(response));
            
        } catch (Exception e) {
            log.error("Error generating image", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("图像生成失败: " + e.getMessage()));
        }
    }

    /**
     * 语音合成
     */
    @PostMapping("/voice")
    @Operation(summary = "语音合成", description = "将文本转换为语音")
    public ResponseEntity<ApiResponse<VoiceSynthesisResponse>> synthesizeVoice(
            @Valid @RequestBody VoiceSynthesisRequest request) {
        
        try {
            log.info("Synthesizing voice for user: {}, text length: {}", 
                    request.getUserId(), request.getText().length());
            
            VoiceSynthesisResponse response = voiceSynthesisService.synthesizeVoice(request);
            
            return ResponseEntity.ok(ApiResponse.success(response));
            
        } catch (Exception e) {
            log.error("Error synthesizing voice", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("语音合成失败: " + e.getMessage()));
        }
    }

    /**
     * 异步语音合成
     */
    @PostMapping("/voice/async")
    @Operation(summary = "异步语音合成", description = "异步将文本转换为语音")
    public ResponseEntity<ApiResponse<String>> synthesizeVoiceAsync(
            @Valid @RequestBody VoiceSynthesisRequest request) {
        
        try {
            log.info("Starting async voice synthesis for user: {}", request.getUserId());
            
            CompletableFuture<VoiceSynthesisResponse> future = 
                    voiceSynthesisService.synthesizeVoiceAsync(request);
            
            // 返回任务ID，客户端可以通过此ID查询结果
            String taskId = "voice_" + System.currentTimeMillis() + "_" + request.getUserId();
            
            return ResponseEntity.ok(ApiResponse.success(taskId));
            
        } catch (Exception e) {
            log.error("Error starting async voice synthesis", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("异步语音合成启动失败: " + e.getMessage()));
        }
    }

    /**
     * 图像风格转换
     */
    @PostMapping("/image/style-transfer")
    @Operation(summary = "图像风格转换", description = "将图像转换为指定风格")
    public ResponseEntity<ApiResponse<ImageGenerationResponse>> convertImageStyle(
            @RequestParam String userId,
            @RequestParam String imagePath,
            @RequestParam String targetStyle) {
        
        try {
            log.info("Converting image style for user: {}, style: {}", userId, targetStyle);
            
            ImageGenerationResponse response = imageGenerationService.convertImageStyle(
                    userId, imagePath, targetStyle);
            
            return ResponseEntity.ok(ApiResponse.success(response));
            
        } catch (Exception e) {
            log.error("Error converting image style", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("图像风格转换失败: " + e.getMessage()));
        }
    }

    /**
     * 下载生成的图像
     */
    @GetMapping("/image/download/{userId}/{filename}")
    @Operation(summary = "下载生成的图像", description = "下载用户生成的图像文件")
    public ResponseEntity<Resource> downloadImage(
            @PathVariable String userId,
            @PathVariable String filename) {
        
        try {
            String imagePath = "uploads/generated-images/" + userId + "/" + filename;
            File file = new File(imagePath);
            
            if (!file.exists()) {
                return ResponseEntity.notFound().build();
            }
            
            Resource resource = new FileSystemResource(file);
            String contentType = Files.probeContentType(Paths.get(imagePath));
            
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType != null ? contentType : "image/png"))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                    .body(resource);
                    
        } catch (Exception e) {
            log.error("Error downloading image: {}/{}", userId, filename, e);
            return ResponseEntity.badRequest().build();
        }
    }

    /**
     * 下载生成的语音
     */
    @GetMapping("/voice/download/{userId}/{filename}")
    @Operation(summary = "下载生成的语音", description = "下载用户生成的语音文件")
    public ResponseEntity<Resource> downloadVoice(
            @PathVariable String userId,
            @PathVariable String filename) {
        
        try {
            String audioPath = "uploads/generated-audio/" + userId + "/" + filename;
            File file = new File(audioPath);
            
            if (!file.exists()) {
                return ResponseEntity.notFound().build();
            }
            
            Resource resource = new FileSystemResource(file);
            String contentType = Files.probeContentType(Paths.get(audioPath));
            
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType != null ? contentType : "audio/mpeg"))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                    .body(resource);
                    
        } catch (Exception e) {
            log.error("Error downloading voice: {}/{}", userId, filename, e);
            return ResponseEntity.badRequest().build();
        }
    }

    /**
     * 获取用户的图像历史
     */
    @GetMapping("/image/history/{userId}")
    @Operation(summary = "获取图像历史", description = "获取用户生成的图像历史记录")
    public ResponseEntity<ApiResponse<List<String>>> getImageHistory(
            @PathVariable String userId,
            @RequestParam(defaultValue = "10") @Min(1) @Max(50) int limit) {
        
        try {
            List<String> history = imageGenerationService.getUserImageHistory(userId, limit);
            return ResponseEntity.ok(ApiResponse.success(history));
            
        } catch (Exception e) {
            log.error("Error getting image history for user: {}", userId, e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("获取图像历史失败: " + e.getMessage()));
        }
    }

    /**
     * 获取用户的语音历史
     */
    @GetMapping("/voice/history/{userId}")
    @Operation(summary = "获取语音历史", description = "获取用户生成的语音历史记录")
    public ResponseEntity<ApiResponse<List<String>>> getVoiceHistory(
            @PathVariable String userId,
            @RequestParam(defaultValue = "10") @Min(1) @Max(50) int limit) {
        
        try {
            List<String> history = voiceSynthesisService.getUserVoiceHistory(userId, limit);
            return ResponseEntity.ok(ApiResponse.success(history));
            
        } catch (Exception e) {
            log.error("Error getting voice history for user: {}", userId, e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("获取语音历史失败: " + e.getMessage()));
        }
    }

    /**
     * 获取支持的声音列表
     */
    @GetMapping("/voice/voices")
    @Operation(summary = "获取支持的声音", description = "获取系统支持的所有声音选项")
    public ResponseEntity<ApiResponse<List<String>>> getSupportedVoices() {
        try {
            List<String> voices = voiceSynthesisService.getSupportedVoices();
            return ResponseEntity.ok(ApiResponse.success(voices));
        } catch (Exception e) {
            log.error("Error getting supported voices", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("获取声音列表失败: " + e.getMessage()));
        }
    }

    /**
     * 获取支持的音频格式
     */
    @GetMapping("/voice/formats")
    @Operation(summary = "获取支持的音频格式", description = "获取系统支持的所有音频格式")
    public ResponseEntity<ApiResponse<List<String>>> getSupportedFormats() {
        try {
            List<String> formats = voiceSynthesisService.getSupportedFormats();
            return ResponseEntity.ok(ApiResponse.success(formats));
        } catch (Exception e) {
            log.error("Error getting supported formats", e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("获取音频格式列表失败: " + e.getMessage()));
        }
    }

    /**
     * 获取用户的多模态输出历史
     */
    @GetMapping("/history/{userId}")
    @Operation(summary = "获取多模态输出历史", description = "获取用户的多模态输出历史记录")
    public ResponseEntity<ApiResponse<List<MultiModalOutputResponse>>> getOutputHistory(
            @PathVariable String userId,
            @RequestParam(defaultValue = "10") @Min(1) @Max(50) int limit) {
        
        try {
            List<MultiModalOutputResponse> history = 
                    multiModalOutputService.getUserOutputHistory(userId, limit);
            return ResponseEntity.ok(ApiResponse.success(history));
            
        } catch (Exception e) {
            log.error("Error getting output history for user: {}", userId, e);
            return ResponseEntity.badRequest()
                    .body(ApiResponse.error("获取输出历史失败: " + e.getMessage()));
        }
    }

    /**
     * 健康检查
     */
    @GetMapping("/health")
    @Operation(summary = "健康检查", description = "检查多模态输出服务的健康状态")
    public ResponseEntity<ApiResponse<String>> healthCheck() {
        return ResponseEntity.ok(ApiResponse.success("多模态输出服务运行正常"));
    }
}